package la.iok.hzsvn.lewin.movie.cloud.controller;

import la.iok.hzsvn.lewin.movie.cloud.config.RedisKey;
import la.iok.hzsvn.lewin.movie.cloud.entity.Role;
import la.iok.hzsvn.lewin.movie.cloud.entity.User;
import la.iok.hzsvn.lewin.movie.cloud.entity.UserRole;
import la.iok.hzsvn.lewin.movie.cloud.service.RoleService;
import la.iok.hzsvn.lewin.movie.cloud.service.UserRoleService;
import la.iok.hzsvn.lewin.movie.cloud.service.UserService;
import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.core.model.SimpleUser;
import la.iok.hzsvn.lewin.movie.core.model.UserVo;
import la.iok.hzsvn.redis.service.RedisService;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.Nullable;
import la.iok.hzsvn.share.response.ListDataResponse;
import la.iok.hzsvn.share.response.SingleDataResponse;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("internal-api/users")
public class UserInternalController {
    private final UserService userService;
    private final UserRoleService userRoleService;
    private final RoleService roleService;
    private final RedisService redisService;
    private final RedisKey redisKey;

    public UserInternalController(UserService userService,
                                  UserRoleService userRoleService,
                                  RoleService roleService,
                                  RedisService redisService,
                                  RedisKey redisKey) {
        this.userService = userService;
        this.userRoleService = userRoleService;
        this.roleService = roleService;
        this.redisService = redisService;
        this.redisKey = redisKey;
    }

    @RequestMapping("login")
    public SingleDataResponse<UserInfo> login(@RequestBody String phoneNumber){
        User user = userService.select(phoneNumber);
        ErrorCode.USERNAME_OR_PASSWORD_ERROR.assertNotNull(user);
        UserInfo userLoginInfo = new UserInfo();
        userLoginInfo.setUsername(user.getPhoneNumber());
        userLoginInfo.setPassword(user.getPassword());
        List<UserRole> userRoles = userRoleService.userRoles(user.getId());
        Set<Long> roleIds = userRoles.stream().filter(ur->Objects.equals(ur.getOrgUnitId(),user.getOrgUnitId())).map(UserRole::getRoleId).collect(Collectors.toSet());
        List<String> rs = Collections.emptyList();
        if(roleIds.size() > 0){
            rs = roleService.list(roleIds).stream().map(Role::getName).collect(Collectors.toList());
        }
        Number bindingId = (Number) redisService.get(redisKey.phoneUserBindingKey(user.getPhoneNumber()));
        userLoginInfo.setRoles(rs);
        Map<String,Object> additional = new HashMap<>();
        additional.put("userId",user.getId());
        additional.put("orgUnitId",user.getOrgUnitId());
        additional.put("userRoles",userRoleService.po2vo(userRoles));
        if(bindingId != null){
            additional.put("wxBindingId",bindingId.longValue());
        }
        userLoginInfo.setAdditional(additional);
        return new SingleDataResponse<>(userLoginInfo);
    }
    @GetMapping("{id}")
    public SingleDataResponse<UserVo> userInfo(@PathVariable Long id){
        return new SingleDataResponse<>(userService.po2vo(userService.select(id)));
    }
    @GetMapping
    public ListDataResponse<SimpleUser> userInfo(Long[] ids){
        return new ListDataResponse<>(userService.users(ids));
    }
    static class UserInfo {
        /**
         * 用户名
         */
        @NotNull
        private String username;
        /**
         * 密码
         */
        @NotNull
        private String password;
        /**
         * 角色
         */
        @Nullable
        private List<String> roles;
        /**
         * 其他附加信息,将会加入到token中
         */
        @Nullable
        private Map<String,Object> additional;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public List<String> getRoles() {
            return roles;
        }

        public void setRoles(List<String> roles) {
            this.roles = roles;
        }

        public Map<String, Object> getAdditional() {
            return additional;
        }

        public void setAdditional(Map<String, Object> additional) {
            this.additional = additional;
        }
    }
}
